﻿using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.Core;
using System.Text;
using System.Web.Script.Serialization;
using System.Data;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.Reflection;

namespace msBsc.SvRef
{
    #region 将对象序列化
    //[Serializable]
    public class ObjectByteArrayConverter
    {
        #region 将对象序列化JSON
        //第一种将object转换为string对象，这种比较简单没有什么可谈的；
        public string ScriptSerialize<T>(T t)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(t);
        }

        //第二种将object转换为xml对象：
        public string ScriptSerializeToXML<T>(T t)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            MemoryStream mem = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(mem, Encoding.UTF8);
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            serializer.Serialize(writer, t, ns);
            writer.Close();
            return Encoding.UTF8.GetString(mem.ToArray());
        }
        //一、将string对象反序列化为object对象
        public T ScriptDeserialize<T>(string strJson)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Deserialize<T>(strJson);
        }
        //二、将string对象反序列化为list对象
        public List<T> JSONStringToList<T>(string strJson)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            List<T> objList = serializer.Deserialize<List<T>>(strJson);
            return objList;
        }
        //三、将string对象反序列化为datatable对象
        public DataTable JSONStringToDataTable<T>(string strJson)
        {
            DataTable dt = new DataTable();
            if (strJson.IndexOf("[") > -1)//如果大于则strJson存放了多个model对象
            {
                strJson = strJson.Remove(strJson.Length - 1, 1).Remove(0, 1).Replace("},{", "};{");
            }
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            string[] items = strJson.Split(';');

            foreach (PropertyInfo property in typeof(T).GetProperties())//通过反射获得T类型的所有属性
            {
                DataColumn col = new DataColumn(property.Name, property.PropertyType);
                dt.Columns.Add(col);
            }
            //循环 一个一个的反序列化
            for (int i = 0; i < items.Length; i++)
            {
                DataRow dr = dt.NewRow();
                //反序列化为一个T类型对象
                T temp = serializer.Deserialize<T>(items[i]);
                foreach (PropertyInfo property in typeof(T).GetProperties())
                {
                    dr[property.Name] = property.GetValue(temp, null);
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }
        //四、将xml对象反序列化为object对象
        public T JSONXMLToObject<T>(string strJson)
        {
            XmlDocument xdoc = new XmlDocument();
            try
            {
                xdoc.LoadXml(strJson);
                XmlNodeReader reader = new XmlNodeReader(xdoc.DocumentElement);
                XmlSerializer ser = new XmlSerializer(typeof(T));
                object obj = ser.Deserialize(reader);
                return (T)obj;
            }
            catch
            {
                return default(T);
            }
        }
        /*
现在用具体的实例来如何调用他们呢?特别要注意的是将xml对象反序列化objcet对象
 public class LoginObject
    {
          public string Account { get; set;}
          public string Password { get; set;}
     }
 1  LoginObject loginObject = new LoginObject { Account = account, Password = password };
 2             ExTools.Manage.Class.CScriptSerialize Serialize = new Class.CScriptSerialize();
 3             //将object对象转换为string
 4              string strJson=Serialize.ScriptSerialize(loginObject);
 5           
 6             //将object对象转换为xml对象
 7             string strJson = Serialize.ScriptSerializeToXML(loginObject);
 8            
 9 
10             //转换为list对象
11              List<LoginObject> list = Serialize.JSONStringToList<LoginObject>(strJson);
12             //将一个xml对象转换为object对象
13            strJson = strJson.Substring(1, strJson.Length - 1);
14             loginObject = Serialize.JSONXMLToObject<LoginObject>(strJson);
15             //将字符串转换为dataTable
16             DataTable dt = Serialize.JSONStringToDataTable<LoginObject>(strJson);
17             //将字符串转换为object对象
18             loginObject = Serialize.ScriptDeserialize<LoginObject>(strJson);
        */

        #endregion

        #region 将对象序列化


        public ArraySegment<byte> ObjectToByteArray(object value)
        {
            using (var ms = new MemoryStream())
            {
                new BinaryFormatter().Serialize(ms, value);

                return new ArraySegment<byte>(ms.GetBuffer(), 0, (int)ms.Length);
            }
        }
        public object ByteArrayToObject(byte[] value)
        {
            if (value == null)
            {
                return null;
            }
            using (var ms = new MemoryStream(value, 0, value.Length))
            {
                return new BinaryFormatter().Deserialize(ms);
            }
        }


        ////Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->#region 可序列化对象到byte数组的相互转换
        ///// <summary>
        ///// 将可序列化对象转成Byte数组
        ///// </summary>
        ///// <param name="o">对象</param>
        ///// <returns>返回相关数组</returns>
        //protected static byte[] ObjectToByteArray(object o)
        //{
        //    MemoryStream ms = new MemoryStream();
        //    BinaryFormatter bf = new BinaryFormatter();
        //    bf.Serialize(ms, o);
        //    ms.Close();
        //    return ms.ToArray();
        //}
        ///// <summary>
        ///// 将可序列化对象转成的byte数组还原为对象
        ///// </summary>
        ///// <param name="b">byte数组</param>
        ///// <returns>相关对象</returns>
        //protected static object ByteArrayToObject(byte[] b)
        //{
        //    MemoryStream ms = new MemoryStream(b, 0, b.Length);
        //    BinaryFormatter bf = new BinaryFormatter();
        //    return bf.Deserialize(ms);
        //}
        #endregion

        #region 采用.net系统自带Gzip压缩类进行流压缩
        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Compress(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                return new byte[] { };
            }
            byte[] bData;
            using (MemoryStream ms = new MemoryStream())
            {
                using (GZipStream stream = new GZipStream(ms, CompressionMode.Compress, true))
                {
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                    //必须把stream流关闭才能返回ms流数据,不然数据会不完整
                    //并且解压缩方法stream.Read(buffer, 0, buffer.Length)时会返回0
                    bData = ms.ToArray();
                    ms.Close();
                    return bData;
                }
            }
        }

        /// <summary>
        /// 解压数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Decompress(byte[] data)
        {
            if (data == null || data.Length == 0)
            {
                return new byte[] { };
            }
            byte[] bData;
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(data, 0, data.Length);
                ms.Position = 0;
                using (GZipStream stream = new GZipStream(ms, CompressionMode.Decompress, true))
                {
                    byte[] buffer = new byte[1024];
                    using (MemoryStream temp = new MemoryStream())
                    {
                        int read = stream.Read(buffer, 0, buffer.Length);
                        while (read > 0)
                        {
                            temp.Write(buffer, 0, read);
                            read = stream.Read(buffer, 0, buffer.Length);
                        }
                        //必须把stream流关闭才能返回ms流数据,不然数据会不完整
                        stream.Close();
                        ms.Close();
                        bData = temp.ToArray();
                        temp.Close();
                        return bData;
                    }
                }
            }
        }
        #endregion

        #region 采用ICSharpCode.SharpZipLib.GZip进行压缩
        /// <summary>
        /// 采用ICShareCode的Gzip类进行byte数组压缩
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public byte[] ICGzipCompress(byte[] b)
        {
            if (b == null || b.Length == 0)
            {
                return new byte[] { };
            }
            byte[] dataBuffer = new byte[4096];
            using (MemoryStream s = new MemoryStream())
            {
                using (GZipOutputStream gz = new GZipOutputStream(s))
                {
                    using (MemoryStream s2 = new MemoryStream(b))
                    {
                        StreamUtils.Copy(s2, gz, dataBuffer);
                        gz.Finish();
                        byte[] z = new byte[gz.Length];
                        z = s.ToArray();
                        return z;
                    }
                }
            }
        }
        /// <summary>
        /// 将采用ICShareCode的Gzip类压缩的byte数组解压缩
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public byte[] ICGzipDecompress(byte[] b)
        {
            if (b == null || b.Length == 0)
            {
                return new byte[] { };
            }
            byte[] dataBuffer = new byte[4096];

            using (MemoryStream u = new MemoryStream(b))
            {
                using (Stream gi = new GZipInputStream(u))
                {
                    using (MemoryStream uu = new MemoryStream())
                    {
                        StreamUtils.Copy(gi, uu, dataBuffer);

                        byte[] z = new byte[uu.Length];
                        z = uu.ToArray();
                        return z;
                    }
                }
            }
        }
        #endregion

        #region 采用ICSharpCode.SharpZipLib.Zip进行压缩
        /// <summary>
        /// 采用ICShareCode的Zip类进行byte数组压缩
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public byte[] ICZipCompress(byte[] b)
        {
            if (b == null || b.Length == 0)
            {
                return new byte[] { };
            }
            using (MemoryStream m = new MemoryStream())
            {
                using (DeflaterOutputStream os = new DeflaterOutputStream(m))
                {
                    os.Write(b, 0, b.Length);
                    os.Finish();
                    byte[] z = m.ToArray();

                    return z;
                }
            }
        }
        /// <summary>
        /// 将采用ICShareCode的Zip类压缩的数组解压缩
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public byte[] ICZipDecompress(byte[] b)
        {
            if (b == null || b.Length == 0)
            {
                return new byte[] { };
            }
            using (MemoryStream m = new MemoryStream())
            {
                using (MemoryStream m2 = new MemoryStream(b))
                {
                    using (InflaterInputStream iis = new InflaterInputStream(m2))
                    {
                        StreamUtils.Copy(iis, m, new byte[4096]);
                        byte[] z = m.ToArray();

                        return z;
                    }
                }
            }
        }
        #endregion

        //// 压缩
        //public static byte[] Compress(byte[] _data)
        //{
        //    if (_data == null || _data.Length == 0)
        //    {
        //        return new byte[] { };
        //    }
        //    MemoryStream source = new MemoryStream(_data);
        //    MemoryStream dest = new MemoryStream();
        //    try
        //    {
        //        Compress(source, dest);
        //        return dest.GetBuffer();
        //    }
        //    catch (SerializationException e)
        //    {
        //        return new byte[] { };
        //    }
        //    finally
        //    {
        //        source.Close();
        //        dest.Close();
        //    }
        //}

        //private static void Compress(Stream source, Stream dest)
        //{
        //    using (GZipStream zipStream = new GZipStream(dest, CompressionMode.Compress, true))
        //    {
        //        byte[] buf = new byte[1024];
        //        int len;
        //        while ((len = source.Read(buf, 0, buf.Length)) > 0)
        //        {
        //            zipStream.Write(buf, 0, len);
        //        }
        //    }
        //}

        //// 解压

        //public static byte[] Decompress(byte[] _data)
        //{
        //    if (_data == null || _data.Length == 0)
        //    {
        //        return new byte[] { };
        //    }
        //    MemoryStream source = new MemoryStream(_data);
        //    MemoryStream dest = new MemoryStream();
        //    try
        //    {
        //        Decompress(source, dest);
        //        return dest.GetBuffer();
        //    }
        //    catch (SerializationException e)
        //    {
        //        return new byte[] { };
        //    }
        //    finally
        //    {
        //        source.Close();
        //        dest.Close();
        //    }
        //}

        //private static void Decompress(Stream source, Stream dest)
        //{
        //    using (GZipStream zipStream = new GZipStream(source, CompressionMode.Decompress, true))
        //    {
        //        byte[] buf = new byte[1024];
        //        int len;
        //        while ((len = zipStream.Read(buf, 0, buf.Length)) > 0)
        //        {
        //            dest.Write(buf, 0, len);
        //        }
        //    }
        //}

        ///<summary> 
        /// 序列化 
        /// </summary> 
        /// <param name="data">要序列化的对象</param> 
        /// <returns>返回存放序列化后的数据缓冲区</returns> 
        public byte[] Serialize(object data, bool blGzip)
        {
            if (data == null)
            {
                return new byte[] { };
            }
            if (data.GetType() == typeof(DataRow))
            {
                DataTable dttem = ((DataRow)data).Table.Clone();
                dttem.Rows.Add(((DataRow)data).ItemArray);
                dttem.AcceptChanges();
                data = dttem;
            }
            if (blGzip)
            {
                return ICGzipCompress(ObjectToByteArray(data).Array);
            }
            else
            {
                return ObjectToByteArray(data).Array;
            }

            //BinaryFormatter formatter = new BinaryFormatter();
            //MemoryStream rems = new MemoryStream();
            //try
            //{
            //    formatter.Serialize(rems, data);
            //    return rems.ToArray();
            //}
            //catch (SerializationException e)
            //{
            //    return new byte[] { };
            //}
            //finally
            //{
            //    rems.Close();
            //}
        }

        /// <summary> 
        /// 反序列化 
        /// </summary> 
        /// <param name="data">数据缓冲区</param> 
        /// <returns>对象</returns> 
        public object Deserialize(byte[] data, bool blGzip)
        {
            if (data == null || data.Length == 0)
            {
                return null;
            }

            if (blGzip)
            {
                return ByteArrayToObject(ICGzipDecompress(data));
            }
            else
            {
                return ByteArrayToObject(data);
            }

            //BinaryFormatter formatter = new BinaryFormatter();
            //MemoryStream rems = new MemoryStream(data);
            //try
            //{
            //    data = null;
            //    return formatter.Deserialize(rems);
            //}
            //catch (SerializationException e)
            //{
            //    return null;
            //}
            //finally
            //{
            //    rems.Close();
            //}
        }

        //public static byte[] ObjectToByteArray(Object obj)
        //{
        //    MemoryStream fs = new MemoryStream();
        //    MemoryStream fsOut = new MemoryStream();
        //    BinaryFormatter formatter = new BinaryFormatter();
        //    try
        //    {
        //        formatter.Serialize(fs, obj);
        //        Compress(fs, fsOut);
        //        return fsOut.ToArray();
        //    }
        //    catch (SerializationException e)
        //    {
        //        return null;
        //    }
        //    finally
        //    {
        //        fs.Close();
        //        fsOut.Close();
        //    }
        //}




        //public static object ByteArrayToObject(Byte[] Buffer)
        //{
        //    BinaryFormatter formatter = new BinaryFormatter();
        //    MemoryStream stream = new MemoryStream(Buffer);
        //    MemoryStream fsOut = new MemoryStream();
        //    try
        //    {
        //        Decompress(stream, fsOut);
        //        return formatter.Deserialize(fsOut);
        //    }
        //    catch
        //    {
        //        return null;
        //    }
        //    finally
        //    {
        //        stream.Close();
        //        fsOut.Close();
        //    }
        //}
    }
    #endregion
}
